package com.jumei.flume.parser;

import com.esotericsoftware.reflectasm.MethodAccess;
import com.jumei.flume.bo.ShuabaoSensorMessage;
import org.apache.commons.lang.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.lang.reflect.Field;
import java.lang.reflect.Modifier;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

public class JsonSplit2HdfsFormatter4Shuabao {

	private final static Logger LOGGER = LoggerFactory.getLogger(JsonSplit2HdfsFormatter4Shuabao.class);
	public final static String SPILT_DFLT = "\001";//  \001
	// for legacy reasons, by default, append a newline to each event written out
    private final String APPEND_NEWLINE = "appendNewline";
    private final boolean APPEND_NEWLINE_DFLT = true;
	
	
	/**
	 * 转换成hdfs识别的格式，默认以 \001 分割
	 * 
	 * @param shuabaoSensorMessage
	 * @return
	 * @throws Exception
	 */
	public String convert2HdfsFormatter(ShuabaoSensorMessage shuabaoSensorMessage) throws Exception {
		StringBuffer sb = new StringBuffer();
		
		Field[] fields = shuabaoSensorMessage.getClass().getDeclaredFields();
        for (Field field : fields) {
            field.setAccessible(true);
            Object fieldValue = field.get(shuabaoSensorMessage);
            if (fieldValue != null) {
            	sb.append(filterCharacter(fieldValue.toString()));
            } else {
            	sb.append("");
            }
            
            sb.append(SPILT_DFLT);//添加分隔符
        }
        
        String s = sb.substring(0, sb.length() - SPILT_DFLT.length());
        
		return s;
	}
	
	
	/**
	 * ASM 提升效率
	 * 
	 * @param shuabaoSensorMessage
	 * @return
	 * @throws Exception
	 */
	public String convert2HdfsFormatter4Asm(ShuabaoSensorMessage shuabaoSensorMessage) throws Exception {
		StringBuffer sb = new StringBuffer();
		
		List<String> fields = fieldMap.get(ShuabaoSensorMessage.class);
        for (String field : fields) {
        	String getKey = ShuabaoSensorMessage.class.getName() + "." + "get" + field;
            Object fieldValue = methodAccess.invoke(shuabaoSensorMessage, methodIndexMap.get(getKey));
            if (fieldValue != null) {
            	sb.append(filterCharacter(fieldValue.toString()));
            } else {
            	sb.append("");
            }
            
            sb.append(SPILT_DFLT);//添加分隔符
        }
        
        String s = sb.substring(0, sb.length() - SPILT_DFLT.length());
        
		return s;
	}
	
	final static MethodAccess methodAccess = MethodAccess.get(ShuabaoSensorMessage.class);
	private static Map<Class, MethodAccess> methodMap = new HashMap<Class, MethodAccess>();
	private static Map<String, Integer> methodIndexMap = new HashMap<String, Integer>();
	private static Map<Class, List<String>> fieldMap = new HashMap<Class, List<String>>();
	
	static {
		Field[] fields = ShuabaoSensorMessage.class.getDeclaredFields();
		List<String> fieldList = new ArrayList<String>(fields.length);
		for (Field field : fields) {
			if (Modifier.isPrivate(field.getModifiers()) && !Modifier.isStatic(field.getModifiers())) { // 是否是私有的，是否是静态的
				// 非公共私有变量
				String fieldName = StringUtils.capitalize(field.getName()); // 获取属性名称
				int getIndex = methodAccess.getIndex("get" + fieldName); // 获取get方法的下标
				int setIndex = methodAccess.getIndex("set" + fieldName); // 获取set方法的下标
				methodIndexMap.put(ShuabaoSensorMessage.class.getName() + "." + "get" + fieldName, getIndex); // 将类名get方法名，方法下标注册到map中
				methodIndexMap.put(ShuabaoSensorMessage.class.getName() + "." + "set" + fieldName, setIndex); // 将类名set方法名，方法下标注册到map中
				fieldList.add(fieldName); // 将属性名称放入集合里
			}
		}
		
		fieldMap.put(ShuabaoSensorMessage.class, fieldList); // 将类名，属性名称注册到map中
		methodMap.put(ShuabaoSensorMessage.class, methodAccess);
	}
	
	
    //过滤字符串隐藏的特殊字符
    private String filterCharacter(String s) {
        if (s == null) {
            return null;
        }

        return s.replaceAll("\n|\r|\t", "");
    }
}
